package com.linshidream.intrachat.simplenio.pipeline.boots;

import com.linshidream.intrachat.simplenio.pipeline.context.MiniChannel;
import com.linshidream.intrachat.simplenio.pipeline.handler.MiniChannelInitializer;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * Created on 2025/8/17 18:21
 *
 * @author linshidream
 * @version 1.0.0
 * @description 启动器
 */

public class MiniServerBootstrap {

    private final ServerSocketChannel serverSocketChannel;

    private final Selector bossSelector;

    private MiniWorker[] workers;

    private MiniChannelInitializer childHandler;

    private int index = 0;

    public MiniServerBootstrap() {
        try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.configureBlocking(false);

            // Boss Selector 主线程只负责监听连接
            bossSelector = Selector.open();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    public MiniServerBootstrap group(MiniEventLoopGroup group) {
        this.workers = group.getWorkers();

        return this;
    }

    public MiniServerBootstrap childHandler(MiniChannelInitializer childHandler) {
        this.childHandler = childHandler;

        return this;
    }

    public MiniServerBootstrap bind(int port) throws IOException {
        serverSocketChannel.bind(new InetSocketAddress(port));
        serverSocketChannel.register(bossSelector, SelectionKey.OP_ACCEPT);

        System.out.println("Mini-Netty 服务端启动成功，监听端口: " + port + ", Worker 线程数量：" + this.workers.length);

        return this;
    }


    private MiniWorker nextWorker() {
        // PacketWorker 线程负责监听读，轮询的负载均衡策略 选择 PacketWorker
        return workers[index++ % workers.length];
    }

    public void sync() throws IOException {
        while (true) {
            bossSelector.select();

            Iterator<SelectionKey> iterator = bossSelector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                iterator.remove();

                if (selectionKey.isAcceptable()) {
                    ServerSocketChannel sc = (ServerSocketChannel) selectionKey.channel();
                    SocketChannel client = sc.accept();

                    MiniWorker worker = this.nextWorker();

                    // 只添加一个 initializer，由它来初始化 pipeline
                    MiniChannel channel = new MiniChannel(client, worker.nextSelector());
                    if (childHandler != null) {
                        channel.pipeline().addLast("initializer", childHandler);
                    }

                    // 开始激活事件 从第一节点开始
                    channel.active();

                    // channel 激活后，立刻开始空闲检测 后面每隔2s一次
                    worker.fireIdleCheck(channel, 0, 2000);

                    // worker 持有的监听器
                    worker.register(channel);
                }
            }
        }
    }


}
